package repository

import (
	"context"
	"errors"

	"github.com/example/video_backend/internal/model"
	"gorm.io/gorm"
)

// CommentRepository 评论仓库接口
type CommentRepository interface {
	Create(ctx context.Context, comment *model.Comment) error
	GetByID(ctx context.Context, id uint) (*model.Comment, error)
	Update(ctx context.Context, comment *model.Comment) error
	Delete(ctx context.Context, id uint) error
	ListByVideoID(ctx context.Context, videoID uint, page, pageSize int) ([]*model.Comment, int64, error)
	ListReplies(ctx context.Context, parentID uint, page, pageSize int) ([]*model.Comment, int64, error)
	IncreaseLikesCount(ctx context.Context, id uint) error
	DecreaseLikesCount(ctx context.Context, id uint) error
	List(ctx context.Context, page, pageSize int, filters map[string]interface{}) ([]*model.Comment, int64, error)
}

// commentRepository 实现CommentRepository接口
type commentRepository struct {
	db *gorm.DB
}

// NewCommentRepository 创建评论仓库实例
func NewCommentRepository(db *gorm.DB) CommentRepository {
	return &commentRepository{db: db}
}

// Create 创建评论
func (r *commentRepository) Create(ctx context.Context, comment *model.Comment) error {
	return r.db.WithContext(ctx).Create(comment).Error
}

// GetByID 根据ID获取评论
func (r *commentRepository) GetByID(ctx context.Context, id uint) (*model.Comment, error) {
	var comment model.Comment
	err := r.db.WithContext(ctx).First(&comment, id).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, err
	}
	return &comment, nil
}

// Update 更新评论
func (r *commentRepository) Update(ctx context.Context, comment *model.Comment) error {
	return r.db.WithContext(ctx).Save(comment).Error
}

// Delete 删除评论
func (r *commentRepository) Delete(ctx context.Context, id uint) error {
	return r.db.WithContext(ctx).Delete(&model.Comment{}, id).Error
}

// ListByVideoID 获取视频的评论列表
func (r *commentRepository) ListByVideoID(ctx context.Context, videoID uint, page, pageSize int) ([]*model.Comment, int64, error) {
	var comments []*model.Comment
	var total int64

	// 计算偏移量
	offset := (page - 1) * pageSize

	// 构建查询
	query := r.db.WithContext(ctx).Where("video_id = ? AND parent_id IS NULL", videoID)

	// 查询总数
	query.Model(&model.Comment{}).Count(&total)

	// 查询分页数据
	err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&comments).Error
	if err != nil {
		return nil, 0, err
	}

	return comments, total, nil
}

// ListReplies 获取评论的回复
func (r *commentRepository) ListReplies(ctx context.Context, parentID uint, page, pageSize int) ([]*model.Comment, int64, error) {
	var replies []*model.Comment
	var total int64

	// 计算偏移量
	offset := (page - 1) * pageSize

	// 构建查询
	query := r.db.WithContext(ctx).Where("parent_id = ?", parentID)

	// 查询总数
	query.Model(&model.Comment{}).Count(&total)

	// 查询分页数据
	err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&replies).Error
	if err != nil {
		return nil, 0, err
	}

	return replies, total, nil
}

// IncreaseLikesCount 增加评论点赞数
func (r *commentRepository) IncreaseLikesCount(ctx context.Context, id uint) error {
	return r.db.WithContext(ctx).Model(&model.Comment{}).Where("id = ?", id).UpdateColumn("likes_count", gorm.Expr("likes_count + 1")).Error
}

// DecreaseLikesCount 减少评论点赞数
func (r *commentRepository) DecreaseLikesCount(ctx context.Context, id uint) error {
	return r.db.WithContext(ctx).Model(&model.Comment{}).Where("id = ?", id).UpdateColumn("likes_count", gorm.Expr("likes_count - 1")).Error
}

// List 获取评论列表（带过滤条件）
func (r *commentRepository) List(ctx context.Context, page, pageSize int, filters map[string]interface{}) ([]*model.Comment, int64, error) {
	var comments []*model.Comment
	var total int64

	// 计算偏移量
	offset := (page - 1) * pageSize

	// 构建查询
	query := r.db.WithContext(ctx)

	// 应用过滤条件
	for key, value := range filters {
		query = query.Where(key, value)
	}

	// 查询总数
	query.Model(&model.Comment{}).Count(&total)

	// 查询分页数据
	err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&comments).Error
	if err != nil {
		return nil, 0, err
	}

	return comments, total, nil
}
